/*
 * @文件描述: 
 * @版本: 
 * @作者: 周晨阳
 * @Date: 2021-08-17 10:00:20
 */
#include "myADC.h"
#ifdef WIN_SIM
/*
 * @文件描述:片上ADC初始化、采集(示波器水平系统)等参数设置模块，及万用表ADC相关的函数
 * @版本:
 * @作者: 周晨阳
 * @Date: 2021-01-15 23:46:16
 * @说明：
 * 
 * 外部需要在初始化ADC之前设置好三个缓冲区，其中一个用来装三个ADC联合的数据
 * 另一个用来装重组的数据，还一个用来记录触发位置信息
 * buffer0：缓冲区0
 * validbuffer：有效数据缓冲区
 * triggerBuffer：触发位置缓冲器
 * 
 * 其中validbuffer的大小应设为buffer0的两倍
 * 外部只需要读取validbuffer中的数据即可，buffer0，1是用来暂存数据的，外界不要去获取里面的数据
 * 这样的目的是为了保证ADC的采样过程中没有干扰，以达到最高采样率
 * 
 * ADC被开启后，触发系统会同时开始工作，在采集的过程中记录触发时刻，用于实现预触发
 * 
 * 缓冲区的数据永远是处于最新的状态，并且是根据触发信号的时机来采集的
 * 可以直接送去给GUI显示
 * 
 * 缓冲区可以是stm32内部ram，也可以是外部ram，因为已经设置好了fsmc和sram的初始化
 * 所以可以直接将数据送至外部ram而不需要其他操作，只需要指定缓冲区的地址和大小即可
 * 
 * ADC的最大采样率可以达到7.2MSa/s左右（采用三个ADC交替采样的模式），
 * 存储深度可以由外界定义，
 * 缓存的地址也由外界定义，
 * 
 * ADCCLK在2分频时为36Mhz
 * 
 * 注意：
 * 此文件中的代码是和硬件紧耦合的，如果需要使用其他硬件，需要重新编写部分函数
 * 只要实现了头文件中的函数，就能保证上层能够正常调用
 */
#include "myADC.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
// #define ADC_CDR_ADDRESS ((uint32_t)0x40012308)
// #define ADC_CCR_ADD ((uint32_t)0x40012304)

// #define ADC1_SMPR1_ADD ((uint32_t)0x4001200C)
// #define ADC1_SMPR2_ADD ((uint32_t)0x40012010)

// #define ADC2_SMPR1_ADD ((uint32_t)0x4001210C)
// #define ADC2_SMPR2_ADD ((uint32_t)0x40012110)

// #define ADC3_SMPR1_ADD ((uint32_t)0x4001220C)
// #define ADC3_SMPR2_ADD ((uint32_t)0x40012210)

// #define ENABLE_TRIGGER_EXTI() EXTI->IMR |= EXTI_Line11     //开启指定的外部中断
// #define DISABLE_TRIGGER_EXTI() EXTI->IMR &= ~(EXTI_Line11) //关闭了指定的外部中断

#define MY_ADC_1 1
#define MY_ADC_2 2
#define MY_ADC_3 3

//缓冲区状态
//缓冲数据已准备好
#define BUFFER_STATE_READY 1
//缓冲数据已失效
#define BUFFER_STATE_INVALID 0
//缓冲数据还未准备好，正在采集，不可打断
#define BUFFER_STATE_NOT_READY 2
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

//开机初始状态下的采样率和时钟分频系数宏
static uint8_t ALL_SamplingTime = 0;
static uint32_t Prescaler = 0;

//adc采样周期和时钟分频系数具体值
static uint16_t ALL_SamplingTimeValue;
static uint8_t PrescalerValue;
//adc的当前状态
static uint8_t sampleState;
static uint8_t adcState;
//ADC当前所使用的采样率，单位Sa/s
static uint32_t CurrentADCSamplingRateValue;
//hold功能开启前的采样率
static uint32_t LastADCSamplingRateValue;
static uint16_t *triggerBufferPointer;
static uint32_t triggerBufferAdd;
static uint32_t triggerBufferSize;
static uint32_t triggerEventCnt = 0;
//dma缓冲区
static uint32_t buffer0Add;
static uint32_t buffer0Size;

static uint32_t buffer1Add;
static uint32_t buffer1Size;

static uint8_t bufferCount;
static uint8_t Mode;
static void (*Callback)(uint8_t, uint32_t) = NULL;

//adc单次转换完成时调用的回调函数,用于万用表模式
static void (*ADC1_Cb)(uint16_t) = NULL;
static void (*ADC2_Cb)(uint16_t) = NULL;
static void (*ADC3_Cb)(uint16_t) = NULL;

//外设配置结构体
// static ADC_InitTypeDef ADC_InitStructure;
// static ADC_CommonInitTypeDef ADC_CommonInitStructure;
// static DMA_InitTypeDef DMA_InitStructure;

//有效数据缓冲区
static uint16_t *ValidBufferAdd;
static uint32_t ValidBufferSize;

//触发系统计数器
static uint32_t *Counter;

//DMA缓冲状态
static uint8_t BufferReady = BUFFER_STATE_NOT_READY;

/* Private function prototypes -----------------------------------------------*/
static void Oscill_ADC_DMA_Init(void);
void Voltage_ADC_GPIO_Init();
void ResistanceMeter_ADC_GPIO_Init();
/* Private functions ---------------------------------------------------------*/

static void delay(uint16_t i)
{
  for (; i > 0; i--)
    ;
}
/**
 * @description: 示波器模式下的DMA中断设置
 * @param {type} 
 * @return {type} 
 */
static void Oscill_ADC_DMA_NVIC_Config(void)
{
  // NVIC_InitTypeDef NVIC_InitStructure;
  // // 优先级分组
  // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // // 配置中断优先级
  // NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  // NVIC_Init(&NVIC_InitStructure);
}
/**
 * @description: //adc中断设置
 * @param {type} 
 * @return {type} 
 */
static void ADC_NVIC_Config(void)
{
  // NVIC_InitTypeDef NVIC_InitStructure;
  // // 优先级分组
  // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // // 配置中断优先级
  // NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
  // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  // NVIC_Init(&NVIC_InitStructure);
}
/**
 * @brief : 示波器模式下的触发系统所使用的外部触发引脚初始化
 * @param {*}
 * @return {*}
 */
static void Oscill_ADC_Trig_Config(void)
{
  // EXTI_InitTypeDef EXTI_InitStructure;
  // GPIO_InitTypeDef GPIO_InitStructure;
  // NVIC_InitTypeDef NVIC_InitStructure;
  // // 优先级分组
  // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // // 配置中断优先级
  // NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  // NVIC_Init(&NVIC_InitStructure);

  // /* Enable GPIOB clock */
  // RCC_AHB1PeriphClockCmd(ADC_TRIG_CLK, ENABLE);
  // /* Enable SYSCFG clock */
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  // /* Configure PF11 pin in input no-pull mode */
  // GPIO_InitStructure.GPIO_Pin = ADC_TRIG_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  // GPIO_Init(ADC_TRIG_PORT, &GPIO_InitStructure);

  // /* Connect EXTI11 Line to PC11 pin */
  // SYSCFG_EXTILineConfig(ADC_EXIT_PORT, EXTI_PinSource11);

  // /* Configure EXTI11 line */
  // EXTI_InitStructure.EXTI_Line = EXTI_Line11;
  // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //
  // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //上升沿触发
  // EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  // EXTI_Init(&EXTI_InitStructure);
  // //ENABLE_TRIGGER_EXTI();
}

/**
 * @brief : 暂停采集，使用的是直接将ADC改为单次转换模式，直接关闭ADC的方法会出问题
 * @param {*}
 * @return {*}
 */
void pauseADC_Sampling(void)
{

  // uint32_t temp;
  // uint32_t i;

  // ADC1->CR2 &= (uint32_t)(~ADC_CR2_CONT);
  // //printf("****pause adc\n");
  // //延时必须加上
  // for (i = 0; i < 6000; i++)
  //   ;
}

/**
 * @brief : 恢复ADC采集
 * @param {*}
 * @return {*}
 */
void resumeADC_Sampling(void)
{
  uint32_t i;

  sampleState = ADC_STATE_SAMPLING;

  triggerEventCnt = 0;
  // DMA_SetCurrDataCounter(ADC_DMA_STREAMx, buffer0Size);
  // for (i = 0; i < buffer0Size * 2; i++)
  // {
  //   triggerBufferPointer[i] = 0;
  // }
  // //printf("****resume adc\n");
  // ADC1->CR2 |= (uint32_t)ADC_CR2_CONT;
  // //ADC_SoftwareStartConv(ADC1);
  // ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART;
  // ADC2->CR2 |= (uint32_t)ADC_CR2_SWSTART;
  // ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART;

  BufferReady = BUFFER_STATE_NOT_READY;
  rt_thread_mdelay(2);
  DMA2_Stream0_IRQHandler();

#ifdef DEBUG_MODE
  // printf("open adc\n");
#endif // DEBUG
}
/**
 * @brief : 设置测量频率用的计数器
 * @param {uint32_t} *counter
 * @return {*}
 */
void setTriggerCounter(uint32_t *counter)
{
  Counter = counter;
}
/**
 * @brief : 外部触发中断处理
 * @param {*}
 * @return {*}
 */
void EXTI15_10_IRQHandler(void)
{
  //printf("into exti\n");
  //   if (EXTI_GetFlagStatus(EXTI_Line11) == SET)
  //   {
  //     (*Counter)++;
  // #ifdef DEBUG_MODE
  //     //printf("exti_line11 set\n");
  // #endif // DEBUG

  //     if (BufferReady == BUFFER_STATE_NOT_READY)
  //     {
  //       //记录产生触发信号时，该采样点在缓冲数据中的序号
  //       triggerBufferPointer[triggerEventCnt++] = buffer0Size - ((uint16_t)(ADC_DMA_STREAMx->NDTR));
  //       //printf("triggerEventCnt %d,event num:%d\n", triggerEventCnt, ((uint16_t)(ADC_DMA_STREAMx->NDTR)));
  //     }
  //     EXTI_ClearFlag(EXTI_Line11);
  //   }
}
/**
 * @brief : 获得一次采集过程中触发事件总数
 * @param {*}
 * @return {uint32_t}一次采集过程中触发事件总数
 */
uint32_t getTriggerEventCnt(void)
{
  return triggerEventCnt;
}
/**
 * @brief : 设置ADC的采样周期
 * @param {uint8_t} channel 暂时只能更改channel 13
 * @param {uint8_t} time ：
 * @return {*}
 */
static void setADCSamplingTime(uint32_t Add, uint8_t channel, uint8_t time)
{
  // SMPx[2:0]：通道 X 采样时间选择 (Channel x sampling time selection)
  // 通过软件写入这些位可分别为各个通道选择采样时间。在采样周期期间，通道选择位必须保持
  // 不变。
  // 000：3 个周期
  // 001：15 个周期
  // 010：28 个周期
  // 011：56 个周期
  // 100：84 个周期
  // 101：112 个周期
  // 110：144 个周期
  // 111：480 个周期
  // switch (time)
  // {
  // case ADC_SampleTime_3Cycles:
  //   /* code */
  //   // BIT_ADDR(Add, 11) = 0;
  //   // BIT_ADDR(Add, 10) = 0;
  //   // BIT_ADDR(Add, 9) = 0;
  //   ALL_SamplingTimeValue = 5;
  //   break;
  // case ADC_SampleTime_15Cycles:
  //   // BIT_ADDR(Add, 11) = 0;
  //   // BIT_ADDR(Add, 10) = 0;
  //   // BIT_ADDR(Add, 9) = 1;
  //   ALL_SamplingTimeValue = 17;
  //   break;
  // case ADC_SampleTime_28Cycles:
  //   // BIT_ADDR(Add, 11) = 0;
  //   // BIT_ADDR(Add, 10) = 1;
  //   // BIT_ADDR(Add, 9) = 0;
  //   ALL_SamplingTimeValue = 30;
  //   break;
  // case ADC_SampleTime_56Cycles:
  //   // BIT_ADDR(Add, 11) = 0;
  //   // BIT_ADDR(Add, 10) = 1;
  //   // BIT_ADDR(Add, 9) = 1;
  //   ALL_SamplingTimeValue = 58;
  //   break;
  // case ADC_SampleTime_84Cycles:
  //   // BIT_ADDR(Add, 11) = 1;
  //   // BIT_ADDR(Add, 10) = 0;
  //   // BIT_ADDR(Add, 9) = 0;
  //   ALL_SamplingTimeValue = 86;
  //   break;
  // case ADC_SampleTime_112Cycles:
  //   // BIT_ADDR(Add, 11) = 1;
  //   // BIT_ADDR(Add, 10) = 0;
  //   // BIT_ADDR(Add, 9) = 1;
  //   ALL_SamplingTimeValue = 114;
  //   break;
  // case ADC_SampleTime_144Cycles:
  //   // BIT_ADDR(Add, 11) = 1;
  //   // BIT_ADDR(Add, 10) = 1;
  //   // BIT_ADDR(Add, 9) = 0;
  //   ALL_SamplingTimeValue = 146;
  //   break;
  // case ADC_SampleTime_480Cycles:
  //   // BIT_ADDR(Add, 11) = 1;
  //   // BIT_ADDR(Add, 10) = 1;
  //   // BIT_ADDR(Add, 9) = 1;
  //   ALL_SamplingTimeValue = 482;
  //   break;
  // default:
  //   // BIT_ADDR(Add, 11) = 1;
  //   // BIT_ADDR(Add, 10) = 1;
  //   // BIT_ADDR(Add, 9) = 1;
  //   ALL_SamplingTimeValue = 482;
  //   break;
  // }
}
/**
 * @brief : 设置adcx的采样周期，只设置ADC_CHANNEL
 * @param {ADC_TypeDef} *adcx
 * @param {uint8_t} time
 * @return {*}
 */
static void setADCx_SamplingTime(uint8_t adcx, uint8_t channel, uint8_t time)
{

  // switch (adcx)
  // {
  // case MY_ADC_1:
  //   setADCSamplingTime(ADC1_SMPR1_ADD, ADC_CHANNEL, time);
  //   break;
  // case MY_ADC_2:
  //   setADCSamplingTime(ADC2_SMPR1_ADD, ADC_CHANNEL, time);
  //   break;
  // case MY_ADC_3:
  //   setADCSamplingTime(ADC3_SMPR1_ADD, ADC_CHANNEL, time);
  //   break;
  // }
}
/**
 * @brief : 设置三个ADC为一样的采样周期
 * @param {uint8_t} channel :暂时无法设置
 * @param {uint8_t} time
 * @return {*}
 */
void setAll_ADC_SamplingTime(uint8_t channel, uint8_t time)
{
  uint32_t i = 0;
  ALL_SamplingTime = time;

  setADCx_SamplingTime(MY_ADC_1, channel, time);
  setADCx_SamplingTime(MY_ADC_2, channel, time);
  setADCx_SamplingTime(MY_ADC_3, channel, time);
}
/**
 * @brief : 设置ADC预分配系数
 * @param {uint32_t } scaler 可以为ADC_Prescaler_Div2，4，6，8
 * @return {*}
 */
void setADC_Prescaler(uint32_t scaler)
{
#define ADC_Prescaler_Div2                         ((uint32_t)0x00000000)
#define ADC_Prescaler_Div4                         ((uint32_t)0x00010000)
#define ADC_Prescaler_Div6                         ((uint32_t)0x00020000)
#define ADC_Prescaler_Div8                         ((uint32_t)0x00030000)

  // 位 17:16 ADCPRE：ADC 预分频器 (ADC prescaler)
  // 由软件置 1 和清零，以选择 ADC 的时钟频率。该时钟为所有 ADC 所共用。
  // 注意：
  // 00：PCLK2 2 分频
  // 01：PCLK2 4 分频
  // 10：PCLK2 6 分频
  // 11：PCLK2 8 分频

  switch (scaler)
  {
  case ADC_Prescaler_Div2:
    // BIT_ADDR(ADC_CCR_ADD, 17) = 0;
    // BIT_ADDR(ADC_CCR_ADD, 16) = 0;
    PrescalerValue = 2;
    break;
  case ADC_Prescaler_Div4:
    // BIT_ADDR(ADC_CCR_ADD, 17) = 0;
    // BIT_ADDR(ADC_CCR_ADD, 16) = 1;
    PrescalerValue = 4;
    break;
  case ADC_Prescaler_Div6:
    // BIT_ADDR(ADC_CCR_ADD, 17) = 1;
    // BIT_ADDR(ADC_CCR_ADD, 16) = 0;
    PrescalerValue = 6;
    break;
  case ADC_Prescaler_Div8:
    // BIT_ADDR(ADC_CCR_ADD, 17) = 1;
    // BIT_ADDR(ADC_CCR_ADD, 16) = 1;
    PrescalerValue = 8;
    break;
  }
  Prescaler = scaler;
}
/**
 * @brief : 设置ADC的分频系数和采样周期，
 * @param {uint8_t} prescale ADC_Prescaler_Div2，4，6，8
 * @param {uint8_t} time ADC_SampleTime_3Cycles  
                          ADC_SampleTime_15Cycles 
                          ADC_SampleTime_28Cycles 
                          ADC_SampleTime_56Cycles 
                          ADC_SampleTime_84Cycles 
                          ADC_SampleTime_112Cycles
                          ADC_SampleTime_144Cycles
                          ADC_SampleTime_480Cycles
 * @return {*}
 */
void setAll_ADC_SampTimeAndPrescale(uint8_t prescale, uint8_t time)
{

  setADC_Prescaler(prescale);
  //setAll_ADC_SamplingTime(ADC_CHANNEL, time);
  CurrentADCSamplingRateValue = (uint32_t)(((72 / PrescalerValue) * 1000000) / ALL_SamplingTimeValue);

  if (sampleState != ADC_STATE_HOLD)
  {
    LastADCSamplingRateValue = CurrentADCSamplingRateValue;
  }
}
/**
 * @brief : 有效缓冲器数据拼装,如果在hold状态则不会更新有效数据，会保持最后一次更新的数据
 * @param {*}
 * @return {*}
 */
static void bufferProcess(void)
{
  //这里被改成模拟生成一些数据
  //如果adc 为hold状态，则不更新validbuffer数据
  if (sampleState == ADC_STATE_HOLD)
  {
    //sampleState = ADC_STATE_IDLE;
    return;
  }

  uint16_t i = 0, j = 0;
  uint32_t *p = (uint32_t *)buffer0Add;
  uint16_t value;
  uint32_t value2;
  uint32_t tmp;
  int tmp2 = 0;
  int max = 2000, min = 300;
  sampleState = ADC_STATE_PROCESSING;
  // printf("start process \n");

  if (ValidBufferAdd != NULL && buffer0Add != NULL)
  {
    for (tmp2 = 0; tmp2 < ValidBufferSize; tmp2++)
    {
      ValidBufferAdd[tmp2] = rand() % (max - min) + min;
    }
    //所有数据拼装完成后ADC状态变为空闲
    sampleState = ADC_STATE_IDLE;
  }
  // printf("end process \n");
}
/**
 * @brief : DMA中断处理
 * @param {*}
 * @return {*}
 */
void DMA2_Stream0_IRQHandler(void)
{

  //   //如果传输完成
  //   if (DMA_GetFlagStatus(ADC_DMA_STREAMx, DMA_FLAG_TCIF0) == SET)
  //   {
  BufferReady = BUFFER_STATE_READY;

  // #ifdef DEBUG_MODE

  // #endif // DEBUG

  pauseADC_Sampling();
  bufferProcess();

  //     //软件清零
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_TCIF0);
  //   }

  //   /*****************以下为错误信号的中断**************/
  //   //现阶段先把所有错误提示都打开，等调试完成后没有问题再全部关闭
  //   //transfer error
  //   if (DMA_GetFlagStatus(ADC_DMA_STREAMx, DMA_FLAG_TEIF0) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     printf("Stream0 transfer error\n");
  //     pauseADC_Sampling();
  //     DMA_Cmd(ADC_DMA_STREAMx, DISABLE);
  //     while (DMA_GetCmdStatus(ADC_DMA_STREAMx) == ENABLE)
  //     {
  //       printf("DMA:wait for disable\n");
  //     }
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_TCIF0);
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_FEIF0);
  //     DMA_ClearITPendingBit(ADC_DMA_STREAMx, DMA_IT_TCIF0);
  //     Oscill_ADC_DMA_Init();

  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_TEIF0);

  // #endif // DEBUG
  //   }
  //   //direct mode error
  //   if (DMA_GetFlagStatus(ADC_DMA_STREAMx, DMA_FLAG_DMEIF0) == SET)
  //   {
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_DMEIF0);
  // #ifdef DEBUG_MODE
  //     printf("Stream0 direct mode error\n");

  // #endif // DEBUG
  //   }
  //   //在刚开机一小段时间内，dma fifo中还没有数据，
  //   //会出现这个错误，等待fifo填满后,就不会出现了
  //   if (DMA_GetFlagStatus(ADC_DMA_STREAMx, DMA_FLAG_FEIF0) == SET)
  //   {
  //     //printf("Stream0 fifo error\n");

  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_FEIF0);
  //   }
}
/**
 * @brief : ADC中断处理，
 * @param {*}
 * @return {*}
 */
void ADC_IRQHandler(void)
{
  //   int i;
  //   //overrun错误中断
  //   if (ADC_GetFlagStatus(ADC1, ADC_FLAG_OVR) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     printf("ADC Overrun\n");
  // #endif

  //     pauseADC_Sampling();
  //     ADC_Cmd(ADC1, DISABLE);
  //     ADC_Cmd(ADC2, DISABLE);
  //     ADC_Cmd(ADC3, DISABLE);
  //     ADC_DMACmd(ADC1, DISABLE);
  //     ADC_MultiModeDMARequestAfterLastTransferCmd(DISABLE);
  //     ADC_ClearFlag(ADC1, ADC_FLAG_OVR);
  //     ADC_ClearFlag(ADC1, ADC_FLAG_STRT);
  //     ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

  //     DMA_Cmd(ADC_DMA_STREAMx, DISABLE);
  //     while (DMA_GetCmdStatus(ADC_DMA_STREAMx) == ENABLE)
  //     {
  //       printf("DMA:wait for disable\n");
  //     }
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_TCIF0);
  //     DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_FEIF0);
  //     DMA_ClearITPendingBit(ADC_DMA_STREAMx, DMA_IT_TCIF0);
  //     Oscill_ADC_DMA_Init();

  //     ADC_ClearFlag(ADC1, ADC_FLAG_OVR);
  //     ADC_ClearFlag(ADC1, ADC_FLAG_STRT);
  //     ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  //   }

  //   if (ADC_GetFlagStatus(ADC1, ADC_FLAG_STRT) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     printf("ADC STRT\n");
  // #endif
  //     ADC_ClearFlag(ADC1, ADC_FLAG_STRT);
  //   }
  //   /********以下为ADC单次转换时使用到的中断****************/
  //   if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     printf("ADC1 conver END\n");
  // #endif
  //     (*ADC1_Cb)(ADC_GetConversionValue(ADC1));
  //     ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  //   }
  //   if (ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     //printf("ADC2 conver END\n");
  // #endif
  //     (*ADC2_Cb)(ADC_GetConversionValue(ADC2));

  //     ADC_ClearFlag(ADC2, ADC_FLAG_EOC);
  //     adcState = 0;
  //   }
  //   if (ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == SET)
  //   {

  // #ifdef DEBUG_MODE
  //     printf("ADC3 conver END\n");
  // #endif
  //     (*ADC3_Cb)(ADC_GetConversionValue(ADC3));

  //     ADC_ClearFlag(ADC3, ADC_FLAG_EOC);
  //   }
}
/**
 * @description: 示波器模式下的DMA初始化
 * @param {*}
 * @return {*}
 */
static void Oscill_ADC_DMA_Init(void)
{

  // /* DMA2 Stream0 channel0 configuration **************************************/
  // DMA_DeInit(ADC_DMA_STREAMx);
  // //ADC1是通道0
  // DMA_InitStructure.DMA_Channel = ADC_DMA_CHANNELx;
  // //外设基地址
  // DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;

  // //缓冲区1地址
  // DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer0Add;

  // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  // //设置缓冲大小
  // DMA_InitStructure.DMA_BufferSize = buffer0Size;
  // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  // DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  // DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  // DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  // DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  // DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  // DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
  // DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;

  // //缓冲区2地址,并设置缓冲区1首先被填装
  // //DMA_DoubleBufferModeConfig(ADC_DMA_STREAMx, (uint32_t)buffer1Add, DMA_Memory_0);
  // //DMA_DoubleBufferModeCmd(ADC_DMA_STREAMx, ENABLE);
  // //使能传输完成中断源和传输错误中断源
  // DMA_ITConfig(ADC_DMA_STREAMx, DMA_IT_TC, ENABLE);
  // DMA_ITConfig(ADC_DMA_STREAMx, DMA_IT_TE, ENABLE);
  // //DMA_ITConfig(ADC_DMA_STREAMx, DMA_IT_FE, ENABLE);

  // //初始化DM
  // DMA_Init(ADC_DMA_STREAMx, &DMA_InitStructure);

  // /* DMA2_Stream0 enable */
  // DMA_Cmd(ADC_DMA_STREAMx, ENABLE);
  // while (DMA_GetCmdStatus(ADC_DMA_STREAMx) == DISABLE)
  // {
  //   printf("DMA:wait for enable\n");
  //   DMA_Cmd(ADC_DMA_STREAMx, ENABLE);
  // }
  // /* ADC Common configuration *************************************************/
  // ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_Interl;
  // ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  // ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
  // ADC_CommonInitStructure.ADC_Prescaler = Prescaler;
  // ADC_CommonInit(&ADC_CommonInitStructure);

  // /* ADC1 regular channel 12 configuration ************************************/
  // ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  // ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  // //持续采集
  // ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  // // //默认波形上升沿触发采集，对应触发电路为下降沿
  // // ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Falling;
  // // //外部引脚Px11为ADC外部触发
  // // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11;

  // ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

  // ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  // ADC_InitStructure.ADC_NbrOfConversion = 1;

  // //使能adc错误中断
  // //  ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
  // ADC_ITConfig(ADC1, ADC_IT_OVR, ENABLE);

  // ADC_Init(ADC1, &ADC_InitStructure);

  // ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ALL_SamplingTime);
  // /* Enable ADC1 DMA */
  // ADC_DMACmd(ADC1, ENABLE);

  // /* ADC2 regular channel 12 configuration ************************************/
  // ADC_Init(ADC2, &ADC_InitStructure);
  // /* ADC2 regular channel12 configuration */
  // ADC_RegularChannelConfig(ADC2, ADC_CHANNEL, 1, ALL_SamplingTime);

  // /* ADC3 regular channel 12 configuration ************************************/
  // ADC_Init(ADC3, &ADC_InitStructure);
  // /* ADC3 regular channel12 configuration */
  // ADC_RegularChannelConfig(ADC3, ADC_CHANNEL, 1, ALL_SamplingTime);

  // /* Enable DMA request after last transfer (multi-ADC mode) ******************/
  // ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

  // /* Enable ADC1 **************************************************************/
  // ADC_Cmd(ADC1, ENABLE);

  // /* Enable ADC2 **************************************************************/
  // ADC_Cmd(ADC2, ENABLE);

  // /* Enable ADC3 **************************************************************/
  // ADC_Cmd(ADC3, ENABLE);
  // //printf("ADC init done...\n");

  if (sampleState != ADC_STATE_HOLD)
  {

    // ADC_SoftwareStartConv(ADC1);
    // ADC_SoftwareStartConv(ADC2);
    // ADC_SoftwareStartConv(ADC3);

    BufferReady = BUFFER_STATE_NOT_READY;

    sampleState = ADC_STATE_SAMPLING;
    rt_thread_mdelay(2);
    DMA2_Stream0_IRQHandler();
  }
}
/**
 * @description: 示波器模式下的相关的GPIO初始化
 * @param {*}
 * @return {*}
 */
static void Oscill_ADC_GPIO_Init(void)
{
  // GPIO_InitTypeDef GPIO_InitStructure;

  // /* Enable peripheral clocks *************************************************/
  // RCC_AHB1PeriphClockCmd(ADC1_2_CHANNEL_GPIO_CLK, ENABLE);
  // RCC_AHB1PeriphClockCmd(ADC_TRIG_CLK, ENABLE);
  // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  // /* Configure ADC Channel 13 pin as analog input *****************************/
  // GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  // GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);

  // //外部触发引脚
  // GPIO_InitStructure.GPIO_Pin = ADC_TRIG_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  // GPIO_Init(ADC_TRIG_PORT, &GPIO_InitStructure);
}
/* Public functions ---------------------------------------------------------*/
/**
 * @description: adc初始化,包括初始化片上ADC，DMA等外设，
 * GPIO等，调用此函数之前，先调用设置缓冲区的函数
 * @param {uint8_t} mode ：0为示波器模式，1为万用表模式
 * @return {*}
 */
void My_ADC_init(uint8_t mode)
{
  //ADC用于示波器模式
  if (mode == MODE_OSCILL)
  {
    Oscill_ADC_GPIO_Init();
    ADC_NVIC_Config();
    Oscill_ADC_Trig_Config();
    Oscill_ADC_DMA_NVIC_Config();
    Oscill_ADC_DMA_Init();
    Mode = MODE_OSCILL;
  }
  //ADC用于万用表模式
  else
  {
    Mode = MODE_MULTIMETER;
  }
}

/**
 * @description: 设置ADC_DMA缓冲区
 * @param {uint8_t} whichBuffer 设置哪一个缓冲区
 * @param {uint32_t} *add 地址
 * @param {uint32_t} bufferSize 大小
 * @return {*}
 */
void setADC_Buffer(uint8_t whichBuffer, uint32_t add, uint32_t bufferSize)
{

  if (whichBuffer == BUFFER_0)
  {
    buffer0Add = add;
    buffer0Size = bufferSize;

    //ADC_DMA_STREAMx->M0AR = add;
    // ADC_DMA_STREAMx->NDTR = bufferSize;

#ifdef DEBUG_MODE

    printf("buffer0 add:0x%lx,size:%d\n", add, bufferSize);
#endif // DEBUG
  }
  else
  {
    buffer1Add = add;
    buffer1Size = bufferSize;
#ifdef DEBUG_MODE
    printf("buffer1 add:0x%lx,size:%d\n", add, bufferSize);
#endif // DEBUG
  }
}
/**
 * @brief : 设置触发缓存
 * @param {uint32_t} add
 * @param {uint32_t} bufferSize
 * @return {*}
 */
void setTriggerBuffer(uint32_t add, uint32_t bufferSize)
{
  triggerBufferAdd = add;
  triggerBufferSize = bufferSize;
  triggerBufferPointer = (uint16_t *)add;
}
/**
 * @description: 设置buffer的数量，不能超过两个
 * @param {uint8_t} count
 * @return {*}
 */
void setBufferCount(uint8_t count) { bufferCount = count; }

/**
 * @description: 获取ADC_DMA缓冲区地址
 * @param {*}
 * @return {*}
 */
uint32_t getADC_BufferAdd(uint8_t whichBuffer)
{
  if (whichBuffer == BUFFER_0)
  {
    return buffer0Add;
  }
  else
  {
    return buffer1Add;
  }
}
/**
 * @description: 获取ADC_DMA缓冲区大小,注意是缓冲区，不是实际存储深度大小
 * @param {uint8_t} whichBuffer
 * @return {*}
 */
uint32_t getADC_BufferSize(uint8_t whichBuffer)
{
  if (whichBuffer == BUFFER_0)
  {
    return buffer0Size;
  }
  else
  {
    return buffer1Size;
  }
}
/**
 * @description: 设置数据准备好时的回调函数
 * @param {uint8_t} 哪一个缓冲区的数据已经准备好
 * @param {uint32_t} 缓冲区内实际有效的数据个数
 * @return {*}
 */
void setSampleFinishCB(void (*callback)(uint8_t, uint32_t))
{
  Callback = callback;
}

/**
 * @description: 获取当前ADC采集器的状态
 * @param {*}
 * @return {uint8_t}adc采样器的状态： ADC_STATE_SAMPLING ,ADC_STATE_IDLE ,ADC_STATE_HOLD 
 */
uint8_t getSampleState(void)
{
  return sampleState;
}
/**
 * @brief : 设置ADC外部触发方式，上升沿或下降沿
 * @param {uint8_t} trigType
 * @return {*}
 */
void setADCTrigType(uint8_t trigType)
{
  // uint32_t tmp = (uint32_t)EXTI_BASE;
  // if (trigType != TRIG_TYPE_RISING)
  // {

  //   EXTI->RTSR |= EXTI_Line11;
  //   EXTI->FTSR &= ~EXTI_Line11;
  // }
  // else
  // {
  //   EXTI->RTSR &= ~EXTI_Line11;
  //   EXTI->FTSR |= EXTI_Line11;
  // }
}
/**
 * @brief : 获取存储深度大小
 * @param {*}
 * @return {uint32_t} 存储深度，单位pts
 */
uint32_t getValidBufferSize(void)
{
  return ValidBufferSize;
}
/**
 * @brief : 实时更改存储深度和缓冲地址
 * @param {uint32_t} add 地址
 * @param {uint32_t} size 存储深度 ，单位pts
 * @return {*}
 */
void setValidBuffer(uint16_t *add, uint32_t size)
{
  ValidBufferAdd = add;
  ValidBufferSize = size;
}
/**
 * @brief : 实时更改adc DMA的缓冲大小
 * @param {uint32_t} size DMA buffer 大小
 * @return {*}
 */
void changeADCBufferSize(uint32_t size)
{
  buffer0Size = size;

  pauseADC_Sampling();
  // DMA_Cmd(ADC_DMA_STREAMx, DISABLE);
  // while (DMA_GetCmdStatus(ADC_DMA_STREAMx) == ENABLE)
  // {
  //   printf("DMA:wait for disable\n");
  // }
  // DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_TCIF0);
  // DMA_ClearFlag(ADC_DMA_STREAMx, DMA_FLAG_FEIF0);
  // DMA_ClearITPendingBit(ADC_DMA_STREAMx, DMA_IT_TCIF0);
  Oscill_ADC_DMA_Init();
  //printf("current buffer size:%d\n", ADC_DMA_STREAMx->NDTR);
}
/**
 * @brief : 设置hold功能，暂停数据更新，
 * @param {uint8_t} 可以是state ADC_STATE_SAMPLING, ADC_STATE_HOLD 
 * @return {*}
 */
void setHoldState(uint8_t state)
{

  //记录hold之前的adc状态，因为adc一共有三种状态
  static uint8_t lastState;

  if (state == ADC_STATE_HOLD)
  {
    //保存hold之前状态，防止状态错乱
    lastState = sampleState;
    sampleState = ADC_STATE_HOLD;
  }
  else if (state == ADC_STATE_SAMPLING)
  {
    //恢复hold之前的adc状态
    sampleState = lastState;
  }
}
/**
 * @brief :  获取ADC采样的数据所使用的采样率
 * @param {*}
 * @return {uint32_t} 采样率，单位Sa/s
 */
uint32_t getCurrentADCSamplingRateValue(void)
{
  return CurrentADCSamplingRateValue;
}
/**
 * @brief : 获取在波形hold前的采样率，单位sa/s
 * @param {*}
 * @return {*}
 */
uint32_t getLastADCSamplingRateValue(void)
{
  printf("LastADC:%ld\n", LastADCSamplingRateValue);
  return LastADCSamplingRateValue;
}
/**
 * @brief : 关闭所有ADC
 * @param {*}
 * @return {*}
 */
void closeADC(void)
{
  // ADC_Cmd(ADC1, DISABLE);
  // ADC_Cmd(ADC2, DISABLE);
  // ADC_Cmd(ADC3, DISABLE);
}

/*********以下为万用表所用到的函数*******/

void setADCxCallbackFun(uint8_t ADCx, void (*cb)(uint16_t))
{
  ADC2_Cb = cb;
}
/**
 * @brief : 万用表应用使用的ADC开始转换
 * @param {*}
 * @return {*}
 */
void MultiMeter_ADC_Start()
{
  adcState = 1;
  // ADC_Cmd(ADC2, ENABLE);
  // ADC_SoftwareStartConv(ADC2);
}
/**
 * @brief : 万用表应用专用的ADC停止函数
 * @param {*}
 * @return {*}
 */
void MultiMeter_ADC_Stop()
{
  // ADC_Cmd(ADC2, DISABLE);
  adcState = 0;
}
/**
 * @brief : 
 * @param {*}
 * @return {*}
 */
uint8_t getADC2_State()
{
  return adcState;
}
/**
 * @brief : 万用表应用专用的ADC初始化函数
 * @param {ADC_TypeDef} *ADCx
 * @param {char} channel
 * @return {*}
 */
// static void ADCx_Mode_Config_auto(ADC_TypeDef *ADCx, char channel)
// {
//   /* ADC Common configuration *************************************************/
//   // ADC_DeInit();
//   // ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
//   // ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
//   // ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
//   // ADC_CommonInitStructure.ADC_Prescaler = Prescaler;
//   // ADC_CommonInit(&ADC_CommonInitStructure);

//   // /* ADC1 regular channel 12 configuration ************************************/
//   // ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
//   // ADC_InitStructure.ADC_ScanConvMode = DISABLE;
//   // //持续采集
//   // ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

//   // ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//   // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

//   // ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//   // ADC_InitStructure.ADC_NbrOfConversion = 1;

//   // //使能adc错误中断
//   // ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
//   // ADC_ITConfig(ADCx, ADC_IT_OVR, ENABLE);

//   // ADC_Init(ADCx, &ADC_InitStructure);

//   // ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_480Cycles);

//   // /* Enable ADC2 **************************************************************/
//   // ADC_Cmd(ADC2, ENABLE);

//   //printf("ADC init done...\n");
// }
/**
 * @brief : 万用表应用专用的ADC初始化函数
 * @param {ADC_TypeDef} *ADCx
 * @param {char} channel
 * @return {*}
 */
// void MultiMeter_ADCx_Init_auto(ADC_TypeDef *ADCx, char channel)
// {
//   ADC_NVIC_Config();
//   ADCx_Mode_Config_auto(ADCx, channel);
// }
/**
 * @description: 电压表adc引脚初始化
 * @param {type}
 * @return {type}
 */
void VoltageADC_GPIO_Init()
{

  // GPIO_InitTypeDef GPIO_InitStructure;

  // //配置adc引脚
  // /* Enable peripheral clocks *************************************************/
  // RCC_AHB1PeriphClockCmd(ADC1_2_CHANNEL_GPIO_CLK, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

  // /* Configure ADC Channel 13 pin as analog input *****************************/
  // GPIO_InitStructure.GPIO_Pin = VOLTAGE_ADC_GPIO_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  // GPIO_Init(VOLTAGE_ADC_GPIO_PORT, &GPIO_InitStructure);
}
/**
 * @description: 欧姆表模块初始化
 * @param {无}
 * @return {无}
 */
void ResistanceADC_GPIO_Init()
{

  // GPIO_InitTypeDef GPIO_InitStructure;

  // //配置adc引脚
  // /* Enable peripheral clocks *************************************************/
  // RCC_AHB1PeriphClockCmd(ADC1_2_CHANNEL_GPIO_CLK, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

  // /* Configure ADC Channel 13 pin as analog input *****************************/
  // GPIO_InitStructure.GPIO_Pin = RESISTANCE_ADC_GPIO_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  // GPIO_Init(RESISTANCE_ADC_GPIO_PORT, &GPIO_InitStructure);
}
/**
 * @description: 电流表GPIO初始化
 * @param {type}
 * @return {type}
 */
void CurrentADC_GPIO_Init()
{

  // GPIO_InitTypeDef GPIO_InitStructure;

  // //配置adc引脚
  // /* Enable peripheral clocks *************************************************/
  // RCC_AHB1PeriphClockCmd(ADC1_2_CHANNEL_GPIO_CLK, ENABLE);
  // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

  // /* Configure ADC Channel 13 pin as analog input *****************************/
  // GPIO_InitStructure.GPIO_Pin = CURRENT_ADC_GPIO_PIN;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  // GPIO_Init(CURRENT_ADC_GPIO_PORT, &GPIO_InitStructure);
}

#endif